package object

import (
	"sync"
	"time"
)

// timeLocker 接口包含基本的锁操作
type timeLocker interface {
	Lock()    // 加锁方法
	Unlock()  // 解锁方法
	RLock()   // 读锁方法
	RUnlock() // 读解锁方法
}

// timeNotLocker 用于实现timeLocker接口的空操作
type timeNotLocker struct{}

func (timeNotLocker) Lock()    {} // 加锁，不执行任何操作
func (timeNotLocker) Unlock()  {} // 解锁，不执行任何操作
func (timeNotLocker) RLock()   {} // 读锁，不执行任何操作
func (timeNotLocker) RUnlock() {} // 读解锁，不执行任何操作

// timeSafeLocker 使用sync.RWMutex实现线程安全的读写锁定
type timeSafeLocker struct {
	locker sync.RWMutex // 声明读写互斥锁
}

func (l *timeSafeLocker) Lock()    { l.locker.Lock() }    // 加锁
func (l *timeSafeLocker) Unlock()  { l.locker.Unlock() }  // 解锁
func (l *timeSafeLocker) RLock()   { l.locker.RLock() }   // 读锁
func (l *timeSafeLocker) RUnlock() { l.locker.RUnlock() } // 读解锁

// Time 结构体用于存储时间值和关联的锁
type Time struct {
	Value  time.Time  // 存储时间值
	locker timeLocker // 使用timeLocker接口实现锁
}

// NewTime 函数创建一个Time实例，可选是否启用线程安全
func NewTime(value time.Time, threadSafe bool) *Time {
	t := &Time{Value: value} // 创建Time实例
	if threadSafe {
		t.locker = &timeSafeLocker{} // 如果需要线程安全，则使用timeSafeLocker
	} else {
		t.locker = timeNotLocker{} // 否则使用timeNotLocker，不进行锁操作
	}
	return t // 返回Time实例
}

// Add 方法为Time增加指定的时间间隔
func (t *Time) Add(d time.Duration) time.Time {
	t.locker.Lock()         // 加锁
	defer t.locker.Unlock() // 方法结束时解锁
	return t.Value.Add(d)   // 增加时间间隔
}

// AddDate 方法为Time增加指定的年月日
func (t *Time) AddDate(years int, months int, days int) time.Time {
	t.locker.Lock()                             // 加锁
	defer t.locker.Unlock()                     // 方法结束时解锁
	return t.Value.AddDate(years, months, days) // 增加指定的年月日
}

// After 方法判断Time是否在另一个时间u之后
func (t *Time) After(u time.Time) bool {
	t.locker.RLock()         // 读锁
	defer t.locker.RUnlock() // 方法结束时读解锁
	return t.Value.After(u)  // 判断时间是否在u之后
}

// AppendFormat 方法将Time按照指定的格式追加到字节切片b中
func (t *Time) AppendFormat(b []byte, layout string) []byte {
	t.locker.RLock()                       // 读锁
	defer t.locker.RUnlock()               // 方法结束时读解锁
	return t.Value.AppendFormat(b, layout) // 将时间按指定格式追加到切片
}

// AsTime 方法返回Time的time.Time表示形式
func (t *Time) AsTime() time.Time {
	t.locker.RLock()         // 读锁
	defer t.locker.RUnlock() // 方法结束时读解锁
	return t.Value           // 返回time.Time表示形式
}

// Before 方法判断Time是否在另一个时间u之前
func (t *Time) Before(u time.Time) bool {
	t.locker.RLock()         // 读锁
	defer t.locker.RUnlock() // 方法结束时读解锁
	return t.Value.Before(u) // 判断时间是否在u之前
}

// Clock 方法返回Time的时钟表示
func (t *Time) Clock() (hour, min, sec int) {
	t.locker.RLock()         // 读锁
	defer t.locker.RUnlock() // 方法结束时读解锁
	return t.Value.Clock()   // 返回时钟表示
}

// Date 方法返回Time的日期表示
func (t *Time) Date() (year int, month time.Month, day int) {
	t.locker.RLock()         // 读锁
	defer t.locker.RUnlock() // 方法结束时读解锁
	return t.Value.Date()    // 返回日期表示
}

// Day 方法返回Time的日期部分
func (t *Time) Day() int {
	t.locker.RLock()         // 读锁
	defer t.locker.RUnlock() // 方法结束时读解锁
	return t.Value.Day()     // 返回日期部分
}

// Equal 方法判断两个Time是否相同
func (t *Time) Equal(u time.Time) bool {
	t.locker.RLock()         // 读锁
	defer t.locker.RUnlock() // 方法结束时读解锁
	return t.Value.Equal(u)  // 判断两个时间是否相同
}

// Format 方法将Time格式化为字符串
func (t *Time) Format(layout string) string {
	t.locker.RLock()              // 读锁
	defer t.locker.RUnlock()      // 方法结束时读解锁
	return t.Value.Format(layout) // 格式化时间为字符串
}

// Get 方法返回Time的当前值
func (t *Time) Get() time.Time {
	t.locker.RLock()         // 读锁
	defer t.locker.RUnlock() // 方法结束时读解锁
	return t.Value           // 返回时间值
}

// GobDecode 方法实现gob.Decoder接口，从传输形式中还原时间
func (t *Time) GobDecode(data []byte) error {
	t.locker.Lock()                // 加锁
	defer t.locker.Unlock()        // 方法结束时解锁
	return t.Value.GobDecode(data) // 从gob数据中还原时间
}

// GobEncode 方法实现gob.Encoder接口，将时间转换为适合传输的形式
func (t *Time) GobEncode() ([]byte, error) {
	t.locker.RLock()           // 读锁
	defer t.locker.RUnlock()   // 方法结束时读解锁
	return t.Value.GobEncode() // 编码时间为gob形式
}

// Hour 方法返回Time的小时部分
func (t *Time) Hour() int {
	t.locker.RLock()         // 读锁
	defer t.locker.RUnlock() // 方法结束时读解锁
	return t.Value.Hour()    // 返回小时部分
}

// In 方法将Time转换为指定时区的时间
func (t *Time) In(loc *time.Location) time.Time {
	t.locker.RLock()         // 读锁
	defer t.locker.RUnlock() // 方法结束时读解锁
	return t.Value.In(loc)   // 转换为指定时区时间
}

// IsZero 方法判断Time是否为零值
func (t *Time) IsZero() bool {
	t.locker.RLock()         // 读锁
	defer t.locker.RUnlock() // 方法结束时读解锁
	return t.Value.IsZero()  // 判断是否为零值
}

// ISOWeek 方法返回Time所在的ISO周数
func (t *Time) ISOWeek() (year, week int) {
	t.locker.RLock()         // 读锁
	defer t.locker.RUnlock() // 方法结束时读解锁
	return t.Value.ISOWeek() // 返回ISO周数
}

// Local 方法将Time转换为本地时区的时间
func (t *Time) Local() time.Time {
	t.locker.RLock()         // 读锁
	defer t.locker.RUnlock() // 方法结束时读解锁
	return t.Value.Local()   // 转换为本地时区时间
}

// Location 方法返回Time的地点信息
func (t *Time) Location() *time.Location {
	t.locker.RLock()          // 读锁
	defer t.locker.RUnlock()  // 方法结束时读解锁
	return t.Value.Location() // 返回地点信息
}

// MarshalBinary 方法将Time编码为二进制形式
func (t *Time) MarshalBinary() ([]byte, error) {
	t.locker.RLock()               // 读锁
	defer t.locker.RUnlock()       // 方法结束时读解锁
	return t.Value.MarshalBinary() // 编码为二进制
}

// MarshalJSON 方法将Time编码为JSON格式
func (t *Time) MarshalJSON() ([]byte, error) {
	t.locker.RLock()             // 读锁
	defer t.locker.RUnlock()     // 方法结束时读解锁
	return t.Value.MarshalJSON() // 编码为JSON格式
}

// MarshalText 方法将Time编码为文本格式
func (t *Time) MarshalText() ([]byte, error) {
	t.locker.RLock()             // 读锁
	defer t.locker.RUnlock()     // 方法结束时读解锁
	return t.Value.MarshalText() // 编码为文本格式
}

// Minute 方法返回Time的分钟部分
func (t *Time) Minute() int {
	t.locker.RLock()         // 读锁
	defer t.locker.RUnlock() // 方法结束时读解锁
	return t.Value.Minute()  // 返回分钟部分
}

// Month 方法返回Time的月份部分
func (t *Time) Month() time.Month {
	t.locker.RLock()         // 读锁
	defer t.locker.RUnlock() // 方法结束时读解锁
	return t.Value.Month()   // 返回月份部分
}

// Nanosecond 方法返回Time的纳秒部分
func (t *Time) Nanosecond() int {
	t.locker.RLock()            // 读锁
	defer t.locker.RUnlock()    // 方法结束时读解锁
	return t.Value.Nanosecond() // 返回纳秒部分
}

// Round 方法将Time舍入到最接近的时间间隔
func (t *Time) Round(d time.Duration) time.Time {
	t.locker.RLock()         // 读锁
	defer t.locker.RUnlock() // 方法结束时读解锁
	return t.Value.Round(d)  // 舍入到指定时间间隔
}

// Second 方法返回Time的秒部分
func (t *Time) Second() int {
	t.locker.RLock()         // 读锁
	defer t.locker.RUnlock() // 方法结束时读解锁
	return t.Value.Second()  // 返回秒部分
}

// Set 方法设置Time的值
func (t *Time) Set(value time.Time) {
	t.locker.Lock()         // 加锁
	defer t.locker.Unlock() // 方法结束时解锁
	t.Value = value         // 设置时间值
}

// Since 方法返回从Time到现在的时间间隔
func (t *Time) Since() time.Duration {
	t.locker.RLock()           // 读锁
	defer t.locker.RUnlock()   // 方法结束时读解锁
	return time.Since(t.Value) // 返回时间间隔
}

// String 方法返回Time的字符串表示形式
func (t *Time) String() string {
	t.locker.RLock()         // 读锁
	defer t.locker.RUnlock() // 方法结束时读解锁
	return t.Value.String()  // 返回字符串表示
}

// Sub 方法返回Time和另一个时间u之间的间隔
func (t *Time) Sub(u time.Time) time.Duration {
	t.locker.RLock()         // 读锁
	defer t.locker.RUnlock() // 方法结束时读解锁
	return t.Value.Sub(u)    // 返回时间间隔
}

// Truncate 方法将Time截断到之前的最近时间间隔
func (t *Time) Truncate(d time.Duration) time.Time {
	t.locker.Lock()            // 加锁
	defer t.locker.Unlock()    // 方法结束时解锁
	return t.Value.Truncate(d) // 截断到指定时间间隔
}

// Until 方法返回从现在到Time的时间间隔
func (t *Time) Until() time.Duration {
	t.locker.RLock()           // 读锁
	defer t.locker.RUnlock()   // 方法结束时读解锁
	return time.Until(t.Value) // 返回时间间隔
}

// UnmarshalBinary 方法从二进制格式解码Time
func (t *Time) UnmarshalBinary(data []byte) error {
	t.locker.Lock()                      // 加锁
	defer t.locker.Unlock()              // 方法结束时解锁
	return t.Value.UnmarshalBinary(data) // 从二进制数据解码时间
}

// UnmarshalJSON 方法从JSON格式解码Time
func (t *Time) UnmarshalJSON(data []byte) error {
	t.locker.Lock()                    // 加锁
	defer t.locker.Unlock()            // 方法结束时解锁
	return t.Value.UnmarshalJSON(data) // 从JSON数据解码时间
}

// UnmarshalText 方法从文本格式解码Time
func (t *Time) UnmarshalText(data []byte) error {
	t.locker.Lock()                    // 加锁
	defer t.locker.Unlock()            // 方法结束时解锁
	return t.Value.UnmarshalText(data) // 从文本数据解码时间
}

// UTC 方法将Time转换为UTC时区的时间
func (t *Time) UTC() time.Time {
	t.locker.RLock()         // 读锁
	defer t.locker.RUnlock() // 方法结束时读解锁
	return t.Value.UTC()     // 转换为UTC时区时间
}

// Unix 方法返回Time的Unix时间戳（秒）
func (t *Time) Unix() int64 {
	t.locker.RLock()         // 读锁
	defer t.locker.RUnlock() // 方法结束时读解锁
	return t.Value.Unix()    // 返回Unix时间戳
}

// UnixMicro 方法返回Time的Unix时间戳（微秒）
func (t *Time) UnixMicro() int64 {
	t.locker.RLock()           // 读锁
	defer t.locker.RUnlock()   // 方法结束时读解锁
	return t.Value.UnixMicro() // 返回Unix时间戳（微秒）
}

// UnixMilli 方法返回Time的Unix时间戳（毫秒）
func (t *Time) UnixMilli() int64 {
	t.locker.RLock()           // 读锁
	defer t.locker.RUnlock()   // 方法结束时读解锁
	return t.Value.UnixMilli() // 返回Unix时间戳（毫秒）
}

// UnixNano 方法返回Time的Unix时间戳（纳秒）
func (t *Time) UnixNano() int64 {
	t.locker.RLock()          // 读锁
	defer t.locker.RUnlock()  // 方法结束时读解锁
	return t.Value.UnixNano() // 返回Unix时间戳（纳秒）
}

// Weekday 方法返回Time的星期表示
func (t *Time) Weekday() time.Weekday {
	t.locker.RLock()         // 读锁
	defer t.locker.RUnlock() // 方法结束时读解锁
	return t.Value.Weekday() // 返回星期表示
}

// Year 方法返回Time的年份部分
func (t *Time) Year() int {
	t.locker.RLock()         // 读锁
	defer t.locker.RUnlock() // 方法结束时读解锁
	return t.Value.Year()    // 返回年份部分
}

// YearDay 方法返回Time在该年中的天数
func (t *Time) YearDay() int {
	t.locker.RLock()         // 读锁
	defer t.locker.RUnlock() // 方法结束时读解锁
	return t.Value.YearDay() // 返回该年的天数
}

// Zone 方法返回Time的时区和时区偏移量
func (t *Time) Zone() (zone string, offset int) {
	t.locker.RLock()         // 读锁
	defer t.locker.RUnlock() // 方法结束时读解锁
	return t.Value.Zone()    // 返回时区和偏移量
}
